﻿#pragma once
#include <string>
#include <msclr\marshal.h>
#include <windows.h>
#include < stdlib.h >
#include < vcclr.h >
#include <tchar.h>
#include <strsafe.h>

using namespace System;

#include "FileOperationCmds.h"
#include "ConceptCmd.h"

using namespace std;
using namespace msclr::interop;
namespace DupConceptLIB {

    using namespace System;
    using namespace System::IO;
	using namespace System::Text;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
    using namespace System::Globalization;
//	using namespace System::Diagnostics;

	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
            InitializeComponent();
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}


    protected: 

    protected: 

    private: System::Windows::Forms::TabControl^  tTabCtrl;

    private: System::Windows::Forms::TabPage^  tTab;

    private: System::Windows::Forms::TabPage^  tabPage2;

    public: System::Windows::Forms::RichTextBox^  tDisplayText;
    private: 





    private: System::Windows::Forms::Button^  tOriBnt;
    private: System::Windows::Forms::TextBox^  tOriText;
    private: System::Windows::Forms::Label^  label1;
    private: System::Windows::Forms::TextBox^  tDesText;

    private: System::Windows::Forms::Label^  label2;
    private: System::Windows::Forms::Button^  button1;







    private: System::Windows::Forms::Button^  tBrowser;
    private: System::Windows::Forms::FolderBrowserDialog^  tFolder;

    private: System::Windows::Forms::RichTextBox^  sErrorLog;
    private: System::Windows::Forms::RichTextBox^  sDoneLog;
    private: System::Windows::Forms::Button^  tF2LoadBnt;

    private: System::Windows::Forms::Label^  label4;
    private: System::Windows::Forms::TextBox^  tF2OriText;

    public: System::Windows::Forms::RichTextBox^  tF2Disp;
    private: 


    private: 




    private: System::ComponentModel::IContainer^  components;









	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
            this->tTabCtrl = (gcnew System::Windows::Forms::TabControl());
            this->tTab = (gcnew System::Windows::Forms::TabPage());
            this->sDoneLog = (gcnew System::Windows::Forms::RichTextBox());
            this->sErrorLog = (gcnew System::Windows::Forms::RichTextBox());
            this->tBrowser = (gcnew System::Windows::Forms::Button());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->tDesText = (gcnew System::Windows::Forms::TextBox());
            this->tOriBnt = (gcnew System::Windows::Forms::Button());
            this->tOriText = (gcnew System::Windows::Forms::TextBox());
            this->tDisplayText = (gcnew System::Windows::Forms::RichTextBox());
            this->tabPage2 = (gcnew System::Windows::Forms::TabPage());
            this->tF2LoadBnt = (gcnew System::Windows::Forms::Button());
            this->label4 = (gcnew System::Windows::Forms::Label());
            this->tF2OriText = (gcnew System::Windows::Forms::TextBox());
            this->tF2Disp = (gcnew System::Windows::Forms::RichTextBox());
            this->tFolder = (gcnew System::Windows::Forms::FolderBrowserDialog());
            this->tTabCtrl->SuspendLayout();
            this->tTab->SuspendLayout();
            this->tabPage2->SuspendLayout();
            this->SuspendLayout();
            // 
            // tTabCtrl
            // 
            this->tTabCtrl->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom) 
                | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tTabCtrl->Controls->Add(this->tTab);
            this->tTabCtrl->Controls->Add(this->tabPage2);
            this->tTabCtrl->Location = System::Drawing::Point(0, 1);
            this->tTabCtrl->Name = L"tTabCtrl";
            this->tTabCtrl->SelectedIndex = 0;
            this->tTabCtrl->Size = System::Drawing::Size(787, 645);
            this->tTabCtrl->TabIndex = 0;
            // 
            // tTab
            // 
            this->tTab->Controls->Add(this->sDoneLog);
            this->tTab->Controls->Add(this->sErrorLog);
            this->tTab->Controls->Add(this->tBrowser);
            this->tTab->Controls->Add(this->button1);
            this->tTab->Controls->Add(this->label2);
            this->tTab->Controls->Add(this->label1);
            this->tTab->Controls->Add(this->tDesText);
            this->tTab->Controls->Add(this->tOriBnt);
            this->tTab->Controls->Add(this->tOriText);
            this->tTab->Controls->Add(this->tDisplayText);
            this->tTab->Location = System::Drawing::Point(4, 22);
            this->tTab->Name = L"tTab";
            this->tTab->Padding = System::Windows::Forms::Padding(3);
            this->tTab->Size = System::Drawing::Size(779, 619);
            this->tTab->TabIndex = 0;
            this->tTab->Text = L"Function1";
            this->tTab->UseVisualStyleBackColor = true;
            // 
            // sDoneLog
            // 
            this->sDoneLog->Location = System::Drawing::Point(339, 180);
            this->sDoneLog->Name = L"sDoneLog";
            this->sDoneLog->Size = System::Drawing::Size(100, 96);
            this->sDoneLog->TabIndex = 9;
            this->sDoneLog->Text = L"";
            this->sDoneLog->Visible = false;
            // 
            // sErrorLog
            // 
            this->sErrorLog->Location = System::Drawing::Point(623, 120);
            this->sErrorLog->Name = L"sErrorLog";
            this->sErrorLog->Size = System::Drawing::Size(100, 96);
            this->sErrorLog->TabIndex = 8;
            this->sErrorLog->Text = L"";
            this->sErrorLog->Visible = false;
            // 
            // tBrowser
            // 
            this->tBrowser->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
            this->tBrowser->Location = System::Drawing::Point(623, 22);
            this->tBrowser->Name = L"tBrowser";
            this->tBrowser->Size = System::Drawing::Size(126, 23);
            this->tBrowser->TabIndex = 7;
            this->tBrowser->Text = L"Load input directory";
            this->tBrowser->UseVisualStyleBackColor = true;
            this->tBrowser->Click += gcnew System::EventHandler(this, &Form1::tBrowser_Click);
            // 
            // button1
            // 
            this->button1->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
            this->button1->Location = System::Drawing::Point(623, 75);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(126, 23);
            this->button1->TabIndex = 6;
            this->button1->Text = L"Save Output file";
            this->button1->UseVisualStyleBackColor = true;
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Location = System::Drawing::Point(6, 120);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(87, 13);
            this->label2->TabIndex = 5;
            this->label2->Text = L"Output message:";
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(6, 58);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(111, 13);
            this->label1->TabIndex = 4;
            this->label1->Text = L"Input dwn information:";
            // 
            // tDesText
            // 
            this->tDesText->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tDesText->Location = System::Drawing::Point(6, 77);
            this->tDesText->Name = L"tDesText";
            this->tDesText->Size = System::Drawing::Size(597, 20);
            this->tDesText->TabIndex = 3;
            this->tDesText->Text = L"QSIC EDA ADDED";
            // 
            // tOriBnt
            // 
            this->tOriBnt->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
            this->tOriBnt->Location = System::Drawing::Point(680, 53);
            this->tOriBnt->Name = L"tOriBnt";
            this->tOriBnt->Size = System::Drawing::Size(99, 23);
            this->tOriBnt->TabIndex = 2;
            this->tOriBnt->Text = L"Load Input file";
            this->tOriBnt->UseVisualStyleBackColor = true;
            this->tOriBnt->Visible = false;
            // 
            // tOriText
            // 
            this->tOriText->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tOriText->Location = System::Drawing::Point(6, 24);
            this->tOriText->Name = L"tOriText";
            this->tOriText->Size = System::Drawing::Size(597, 20);
            this->tOriText->TabIndex = 1;
            // 
            // tDisplayText
            // 
            this->tDisplayText->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom) 
                | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tDisplayText->Location = System::Drawing::Point(3, 136);
            this->tDisplayText->Name = L"tDisplayText";
            this->tDisplayText->Size = System::Drawing::Size(773, 483);
            this->tDisplayText->TabIndex = 0;
            this->tDisplayText->Text = L"";
            // 
            // tabPage2
            // 
            this->tabPage2->Controls->Add(this->tF2LoadBnt);
            this->tabPage2->Controls->Add(this->label4);
            this->tabPage2->Controls->Add(this->tF2OriText);
            this->tabPage2->Controls->Add(this->tF2Disp);
            this->tabPage2->Location = System::Drawing::Point(4, 22);
            this->tabPage2->Name = L"tabPage2";
            this->tabPage2->Padding = System::Windows::Forms::Padding(3);
            this->tabPage2->Size = System::Drawing::Size(779, 457);
            this->tabPage2->TabIndex = 1;
            this->tabPage2->Text = L"Function2";
            this->tabPage2->UseVisualStyleBackColor = true;
            // 
            // tF2LoadBnt
            // 
            this->tF2LoadBnt->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
            this->tF2LoadBnt->Location = System::Drawing::Point(632, 9);
            this->tF2LoadBnt->Name = L"tF2LoadBnt";
            this->tF2LoadBnt->Size = System::Drawing::Size(126, 26);
            this->tF2LoadBnt->TabIndex = 11;
            this->tF2LoadBnt->Text = L"Load input directory";
            this->tF2LoadBnt->UseVisualStyleBackColor = true;
            this->tF2LoadBnt->Click += gcnew System::EventHandler(this, &Form1::sF2LoadBnt_Click);
            // 
            // label4
            // 
            this->label4->AutoSize = true;
            this->label4->Location = System::Drawing::Point(3, 50);
            this->label4->Name = L"label4";
            this->label4->Size = System::Drawing::Size(87, 13);
            this->label4->TabIndex = 10;
            this->label4->Text = L"Output message:";
            // 
            // tF2OriText
            // 
            this->tF2OriText->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tF2OriText->Location = System::Drawing::Point(6, 13);
            this->tF2OriText->Name = L"tF2OriText";
            this->tF2OriText->Size = System::Drawing::Size(597, 20);
            this->tF2OriText->TabIndex = 9;
            // 
            // tF2Disp
            // 
            this->tF2Disp->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom) 
                | System::Windows::Forms::AnchorStyles::Left) 
                | System::Windows::Forms::AnchorStyles::Right));
            this->tF2Disp->Location = System::Drawing::Point(3, 66);
            this->tF2Disp->Name = L"tF2Disp";
            this->tF2Disp->Size = System::Drawing::Size(773, 380);
            this->tF2Disp->TabIndex = 8;
            this->tF2Disp->Text = L"";
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(787, 647);
            this->Controls->Add(this->tTabCtrl);
            this->Name = L"Form1";
            this->Text = L"Duplicate Concept Tool";
            this->tTabCtrl->ResumeLayout(false);
            this->tTab->ResumeLayout(false);
            this->tTab->PerformLayout();
            this->tabPage2->ResumeLayout(false);
            this->tabPage2->PerformLayout();
            this->ResumeLayout(false);

        }
        private:
            static bool s_SpecialPart = false;
			static bool s_MultiPart = false;
			static String^ subOldPartRoot="";
			static String^ subNewPartRoot="";
            enum class eErrorCode { FOLDER_NOT_FOUND, 
                                    FILE_NOT_FOUND,
                                    DIRECTORY_FILE_IS_NOT_CONTAIN_PATH,
                                    FILE_IS_NOT_VALID_FORMAT,
                                    PART_IS_NOT_EXISTS_IN_CONCEPT_FILE,
                                    NEW_PART_IS_EXISTS_IN_NEW_CONCEPT_FILE,
                                    PART_IS_NOT_EXISTS_IN_REPORT_FILE,
                                    PART_IS_NOT_EXISTS_IN_PPT_FILE,
                                    CONCEPT01_IS_NOT_EXISTS_IN_REPORT_FILE,
									NEW_PART_IS_EXISTS_IN_NEW_PPT_FILE,
                                    UNKNOWN_ERROR
                                  };

            void ClearErrorLog()
            {
                sErrorLog->Clear();
            }

            void ClearDoneLog()
            {
                sDoneLog->Clear();
            }

            void AddMsg(String^ msg)
            {
                tDisplayText->Text += msg + System::Environment::NewLine;
                tDisplayText->Update();
            }

            void SaveErrorLog(String^ path, String^ fileName)
            {
                String^ fullFileName = path + "\\" + fileName;
                if (true == File::Exists(fullFileName))
                {
                    File::Delete(fullFileName);
                }

                File::WriteAllLines(fullFileName, sErrorLog->Lines);
            }

            void SaveDoneLog(String^ path, String^ fileName)
            {
                String^ fullFileName = path + "\\" + fileName;
                if (true == File::Exists(fullFileName))
                {
                    File::Delete(fullFileName);
                }

                File::WriteAllLines(fullFileName, sDoneLog->Lines);
            }

            void AddErrorLog(eErrorCode errorCode, String^ iPart, String^ path)
            {
                switch (errorCode)
                {
                case eErrorCode::FOLDER_NOT_FOUND:
                    {
                        sErrorLog->Text += "Cannot find folder: "+ path + System::Environment::NewLine;
                    } break;

                case eErrorCode::FILE_NOT_FOUND:
                    {
                        sErrorLog->Text += "File not found: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::DIRECTORY_FILE_IS_NOT_CONTAIN_PATH:
                    {
                        sErrorLog->Text += "Cannot file the Path in file directory: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::FILE_IS_NOT_VALID_FORMAT:
                    {
                        sErrorLog->Text += "File has invalid format data: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::PART_IS_NOT_EXISTS_IN_CONCEPT_FILE:
                    {
                        sErrorLog->Text += "Original ConceptLIB name: \"" + iPart + "\" is not found in Original Conceptlib database: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::NEW_PART_IS_EXISTS_IN_NEW_CONCEPT_FILE:
                    {
                        sErrorLog->Text += "New Conceptlib name: \"" + iPart + "\" is existed in new conceptlib database: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::PART_IS_NOT_EXISTS_IN_REPORT_FILE:
                    {
                        sErrorLog->Text += "Original part name: \"" + iPart +"\"is not found in Original report database: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::PART_IS_NOT_EXISTS_IN_PPT_FILE:
                    {
                        sErrorLog->Text += "Original part name: \"" + iPart + "\" not found in PPT file: " + path + System::Environment::NewLine;
                    } break;

                case eErrorCode::CONCEPT01_IS_NOT_EXISTS_IN_REPORT_FILE:
                    {
                        sErrorLog->Text += "\"Concept01\" of part: \"" + iPart + "\" is not exist in report file: " + path + System::Environment::NewLine;
                    } break;
				case eErrorCode::NEW_PART_IS_EXISTS_IN_NEW_PPT_FILE:
					{
						sErrorLog->Text += "New Conceptlib name: \"" + iPart + "\" is existed in new PPT file: " + path + System::Environment::NewLine;
					} break;
                case eErrorCode::UNKNOWN_ERROR:
                default:
                    {
                        sErrorLog->Text += "Unknown error" + System::Environment::NewLine;
                    } break;
                }
            }

            String^ FindFolder(String^ dirPath, String^ partialFolderName)
            {
                String^ fullDirPath = cFileOperationCmds::FindFolder(dirPath, partialFolderName);
                if ( "" == fullDirPath )
                {
                    AddErrorLog(eErrorCode::FOLDER_NOT_FOUND, "", dirPath + "\\" + partialFolderName);
                }

                return (fullDirPath);
            }

            String^ FindFile(String^ dirPath, String^ partialFileName)
            {
                String^ fullFileName = cFileOperationCmds::FindFile(dirPath, partialFileName);
                if(""==fullFileName)
                {
                    AddErrorLog(eErrorCode::FILE_NOT_FOUND, "", dirPath + "\\" + partialFileName);
                }

                return (fullFileName);
            }

            String^ FindFileWithoutAddLog(String^ dirPath, String^ partialFileName)
            {
                return (cFileOperationCmds::FindFile(dirPath, partialFileName));
            }

            void FillNullString(array<String^>^ searchLines, int startIdx)
            {
                for (int i=startIdx; i<searchLines->Length; i++)
                {
                    searchLines[i] = "";
                }
            }

            int FindLineIndexInFile(array<String^>^ searchLines, String^ str)
            {
                for (int i=0; i<searchLines->Length; i++)
                {
                    if ("" != searchLines[i])
                    {
                        if (searchLines[i]->Contains(str))
                        {
                            return (i);
                        }
                    }
                }
                return (-1);
            }

            int FindLineIndexInFile(array<String^>^ searchLines, String^ str, int startIdx)
            {
                for (int i=startIdx; i<searchLines->Length; i++)
                {
                    if ("" != searchLines[i])
                    {
                        if (searchLines[i]->Contains(str))
                        {
                            return (i);
                        }
                    }
                }
                return (-1);
            }

            int FindLineIndexInFileWithTwoString(array<String^>^ searchLines, String^ str1, String^ str2)
            {
                for (int i=0; i<searchLines->Length; i++)
                {
                    if ("" != searchLines[i])
                    {
                        if (searchLines[i]->Contains(str1) && searchLines[i]->Contains(str2))
                        {
                            return (i);
                        }
                    }
                }
                return (-1);
            }


            int FindLineIndexInFile(RichTextBox^ searchFile, String^ str)
            {
                for (int i=0; i<searchFile->Lines->Length; i++)
                {
                    if (searchFile->Lines[i]->Contains(str))
                    {
                        return (i);
                    }
                }
                return (-1);
            }

            int FindLineIndexInFile(RichTextBox^ searchFile, String^ str, int startIdx)
            {
                for (int i=startIdx; i<searchFile->Lines->Length; i++)
                {
                    if (searchFile->Lines[i]->Contains(str))
                    {
                        return (i);
                    }
                }
                return (-1);
            }

            String^ GetStatusString(String^ lineStr)
            {
                String^ statusStr = "";
                int startStatusStrIndex = lineStr->IndexOf(",") + 1;
                int endStatusStrIndex = lineStr->IndexOf(",", startStatusStrIndex);

                if (-1 != startStatusStrIndex && -1 != endStatusStrIndex)
                {
                    statusStr = lineStr->Substring(startStatusStrIndex, endStatusStrIndex - startStatusStrIndex);
                }
                return (statusStr);
            }

            bool ProcessDuplicatePart(String^ conceptLibPath, String^ conceptPath, String^ family, String^ oldPart, String^ oldPartName, String^ oldPartNumber, String^ newPart, String^ newPartName, String^ newPartNumber)
            {
                int fStartIdx, fEndIdx;

                String^ familyFolderName = family->Replace("-", "_");
                String^ familyPath = FindFolder(conceptPath, familyFolderName);
                if ( "" == familyPath )
                {
                    AddMsg("  --ERROR-- Can't find folder: " + conceptPath + "\\" + familyFolderName);
                    AddErrorLog(eErrorCode::FOLDER_NOT_FOUND, "", conceptPath + "\\" + familyFolderName);
                    return (false);
                }

                // Step 4.2 Rename folder
                String^ oldPartFolder = "";
                String^ str = "";
                if (true == s_SpecialPart)
                {
                    oldPartFolder = familyPath + "\\" + oldPartName;
                    str = FindFolder(familyPath, oldPartName);
                } 
                else
                {
                    oldPartFolder = familyPath + "\\" + oldPart->Replace("-", "#2d");
                    str = FindFolder(familyPath, oldPart->Replace("-", "#2d"));
                }
                if ("" == str || oldPartFolder->ToUpper() != str->ToUpper())
                {
                    return (false);
                }

                String^ newPartFolder = oldPartFolder->Replace(oldPartName, newPartName)->Replace("#2d" + oldPartNumber, "#2d" + newPartNumber);

                if (Directory::Exists(newPartFolder))
                {
                    if (true == s_SpecialPart)
                    {
                        return (true);
                    }

                    cFileOperationCmds::RemoveFolder(newPartFolder);
                }

                if ( 0 != cFileOperationCmds::CopyFolder(oldPartFolder, newPartFolder))
                {
                    AddMsg("  --ERROR-- Can't copy folder from " + oldPartFolder + " to " + newPartFolder);
                    return (false);
                }

                if (Directory::Exists(newPartFolder + "\\entity"))
                {
                    if ( 0 != cFileOperationCmds::RemoveFolder(newPartFolder + "\\entity"))
                    {
                        return (false);
                    }
                }

                String^ chipsFolder = FindFolder(newPartFolder, "chips");
                if ( "" == chipsFolder )
                {
                    AddMsg("  --ERROR-- Can't find folder: " + newPartFolder + "\\chips");
                    return (false);
                }
                chipsFolder = chipsFolder->ToUpper();

                String^ tempFileName = FindFile(chipsFolder, "chips");
                if ("" == tempFileName)
                {
                    AddMsg("  --ERROR-- Can't find file: " + chipsFolder + "\\chips.prt");
                    return (false);
                }

                String^ tempStr = "";
                String^ oldValue = (true == s_SpecialPart)? oldPartName: oldPart;
                String^ newValue = (true == s_SpecialPart)? newPartName: newPart;
                array<String^>^ tempLines = File::ReadAllLines(tempFileName);
                for (int l=0; l<tempLines->Length; l++)
                {
                    tempStr = tempLines[l]->ToUpper();
                    if (true == tempStr->Contains("PRIMITIVE"))
                    {
                        tempStr = tempStr->Replace(oldValue, newValue);
                        tempLines[l] = tempStr;
                    } 
                    else if (true == tempStr->Contains("PART_NAME"))
                    {
                        tempStr = tempStr->Replace(oldValue, newValue);
                        tempLines[l] = tempStr;
                    }
                    else if (true == tempStr->Contains("BODY_NAME"))
                    {
                        tempStr = tempStr->Replace(oldValue, newValue);
                        tempLines[l] = tempStr;
                    }
                }
                File::WriteAllLines(tempFileName, tempLines);

                //step 4.5 Modify my_edit.bat
                String^ entityPath = FindFolder(conceptLibPath, "HowtoGenerate_ConceptLib_entity");
                if ( "" == entityPath )
                {
                    AddMsg("  --ERROR-- Can't find folder: " + conceptLibPath + "\\HowtoGenerate_ConceptLib_entity");
                    return (false);
                }
                tempFileName = FindFile(entityPath, "my_edit.bat");
				String^ editBat = tempFileName;

                if ("" == tempFileName)
                {
                    AddMsg("  --ERROR-- Can't find file: " + entityPath + "\\my_edit.bat");
                    return (false);
                }
                tempLines = File::ReadAllLines(tempFileName);
                for (int l=0; l<tempLines->Length; l++)
                {
                    tempStr = tempLines[l];
                    if (true == tempStr->Contains("-proj ") && true == tempStr->Contains(".cpm"))
                    {
                        fStartIdx = tempStr->IndexOf("-proj ") + 6;
                        fEndIdx   = tempStr->IndexOf(".cpm");
                        String^ oldFamily = tempStr->Substring(fStartIdx, fEndIdx - fStartIdx);
						//repair incorrect family name in Preport database file
                        tempStr = tempStr->Replace(oldFamily, family->ToLower()->Replace("-", "_"));
						//tempStr = tempStr->Replace(oldFamily, family->ToLower());
                        tempLines[l] = tempStr;
                        break;
                    }
                }
                File::WriteAllLines(tempFileName, tempLines);

                //step 4.5 Modify my_edit.scr
                tempFileName = FindFile(entityPath, "my_edit.scr");
                if ("" == tempFileName)
                {
                    AddMsg("  --ERROR-- Can't find file: " + entityPath + "\\my_edit.scr");
                    return (false);
                }
                tempLines = File::ReadAllLines(tempFileName);
                for (int l=0; l<tempLines->Length; l++)
                {
                    tempStr = tempLines[l];
                    if (true == tempStr->Contains("edit ") && true == tempStr->Contains(".sym"))
                    {
                        fStartIdx = tempStr->IndexOf("edit ") + 5;
                        fEndIdx   = tempStr->IndexOf(".sym");
                        String^ tempPart = tempStr->Substring(fStartIdx, fEndIdx - fStartIdx);
                        String^ tempNewPart = (true == s_SpecialPart)? newPartName: newPart;
                        tempStr = tempStr->Replace(tempPart, tempNewPart);
                        tempLines[l] = tempStr;
                        break;
                    }
                }
                File::WriteAllLines(tempFileName, tempLines);

#if 1
                //TODO: Run my_edit.bat on Windows command prompt.
				marshal_context context;
				LPCTSTR myEditBat = context.marshal_as<const TCHAR*>(editBat);
				SHELLEXECUTEINFOW ShExecInfo = {0};
				ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
				ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
				ShExecInfo.hwnd = NULL;
				ShExecInfo.lpVerb = NULL;					
				ShExecInfo.lpFile = myEditBat;
				ShExecInfo.lpParameters = NULL;	
				ShExecInfo.lpDirectory = NULL;
				//	ShExecInfo.nShow = SW_SHOW;
				ShExecInfo.nShow = NULL;
				ShExecInfo.hInstApp = NULL;	
				ShellExecuteExW(&ShExecInfo);
				WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
				//Sleep(1000);//1000 is 1s
				
#endif
                return (true);
            }


            bool ProcessPptFile(String^ conceptPath, String^ family, String^ oldPart, String^ oldPartName, String^ newPart, String^ newPartName)
            {
                String^ formattedFamily = family->ToLower()->Replace("-", "_");
                String^ pptPath = conceptPath + "\\PPT";
                if (false == Directory::Exists(pptPath))
                {
                    AddMsg("  --ERROR-- Can't find folder: " + pptPath);
                    AddErrorLog(eErrorCode::FOLDER_NOT_FOUND, "", pptPath);
                    return (false);
                }
                String^ pptFileName = pptPath + "\\" + formattedFamily + ".ppt";
                if (false == File::Exists(pptFileName))
                {
                    AddMsg("  --ERROR-- Can't find file: " + pptFileName);
                    AddErrorLog(eErrorCode::FILE_NOT_FOUND, "", pptFileName);
                    return (false);
                }

                String^ globalChangeFileName = conceptPath + "\\global_change.txt";
                if (false == File::Exists(globalChangeFileName))
                {
                    AddErrorLog(eErrorCode::FILE_NOT_FOUND, "", globalChangeFileName);
                    return (false);
                } 

                array<String^>^ globalChangeFile;
                globalChangeFile = File::ReadAllLines(globalChangeFileName);

                array<String^>^ oldPptFile = File::ReadAllLines(pptFileName);
                array<String^>^ newPptFile;
                String^ pptNewFileName = pptPath + "\\new_" + formattedFamily + ".ppt";
                if (false == File::Exists(pptNewFileName))
                {
                    newPptFile = gcnew array<String^>(2);
                    // if not exist, create new newPptFile
                    newPptFile[0] = oldPptFile[0];
                    newPptFile[1] = "END.";
                }
                else
                {
                    // if newPptFile exist, load it 
                    newPptFile = File::ReadAllLines(pptNewFileName);
                }

                int oldPartIdx = FindLineIndexInFile(oldPptFile, oldPart);
                if (-1 == oldPartIdx)
                {
                    AddErrorLog(eErrorCode::PART_IS_NOT_EXISTS_IN_PPT_FILE, oldPart, pptFileName);
                    return (false);
                }
                String^ strLine = oldPptFile[oldPartIdx];
                int     newPartIdx = 0;

                // if part has only one value, copy 4 lines to newPptFile
                if (true == strLine->Contains("PART "))
                {
                    // add new part to ppt file
                    if (-1 == FindLineIndexInFile(newPptFile, newPart))
                    {
                        // If not exist, add to newPptFile
                        newPartIdx = FindLineIndexInFile(newPptFile, "END.");
                        if (-1 == newPartIdx)
                        {
                            AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", pptNewFileName);
                            return (false);
                        }
						String^ oldPartTemp="";
						String^ newPartTemp="";
						if(true==s_MultiPart)
						{
							newPartTemp=subNewPartRoot;
							oldPartTemp=subOldPartRoot;
						}
						else
						{
							newPartTemp=newPart;
							oldPartTemp=oldPart;
						}
                        newPptFile[newPartIdx - 1] += System::Environment::NewLine + oldPptFile[oldPartIdx]->Replace(oldPart, newPart)            \
                            + System::Environment::NewLine + oldPptFile[oldPartIdx + 1]                                   \
                            + System::Environment::NewLine + oldPptFile[oldPartIdx + 2]->Replace(oldPartTemp, newPartTemp)        \
                            + System::Environment::NewLine + oldPptFile[oldPartIdx + 3];
                    }

                    //add new part to global_change.txt
                    if (-1 == FindLineIndexInFile(globalChangeFile, newPart))
                    {
                        for (int k=1; k<globalChangeFile->Length; k++)
                        {
                            if (")" == globalChangeFile[k])
                            {
                                globalChangeFile[k-1]  += System::Environment::NewLine + "  ( _globalModify"
                                                        + System::Environment::NewLine + "    ( -Scope Design )"
                                                        + System::Environment::NewLine + "    ( -Save true )"
                                                        + System::Environment::NewLine + "    ( -HardProp true )"
                                                        + System::Environment::NewLine + "    ( -FromLib \"" + family->ToUpper() + "\" )"
                                                        + System::Environment::NewLine + "    ( -FromCell \"" + oldPart + "\" )"
                                                        + System::Environment::NewLine + "    ( -FromProp \"PART_NUMBER\" \"" + oldPart + "\" )"
                                                        + System::Environment::NewLine + "    ( -FromVer \"*\" )"
                                                        + System::Environment::NewLine + "    ( -ToLib \"" + family->ToUpper() + "\" )"
                                                        + System::Environment::NewLine + "    ( -ToCell \"" + newPart + "\" )"
                                                        + System::Environment::NewLine + "    ( -toProp \"PART_NUMBER\" \"" + newPart + "\" )"
                                                        + System::Environment::NewLine + "    ( -ToVer \"*\" )"
                                                        + System::Environment::NewLine + "  )";
                            }
                        }
                        File::WriteAllLines(globalChangeFileName, globalChangeFile);
                    }
                }
                else
                {                    
					// Part has many values, just copy the value line of part to the newPptFile
                    int oldContainsPartIdx = oldPartIdx;
                    do 
                    {
                        --oldContainsPartIdx;
                    } while (0 < oldContainsPartIdx && false == oldPptFile[oldContainsPartIdx]->Contains("PART "));
                    if (0 >= oldContainsPartIdx)
                    {
                        AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", pptFileName);
                        return (false);
                    }

                    newPartIdx = FindLineIndexInFile(newPptFile, newPartName);
                    if (-1 == newPartIdx)
                    {
 						// If new PPT file does not contain this part, add newpart
                        newPartIdx = FindLineIndexInFile(newPptFile, "END.");
                        if (-1 == newPartIdx)
                        {
                            AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", pptFileName);
                            return (false);
                        }
                        newPptFile[newPartIdx - 1] += System::Environment::NewLine + oldPptFile[oldContainsPartIdx]->Replace(oldPartName, newPartName)    \
                                                   + System::Environment::NewLine + oldPptFile[oldContainsPartIdx + 1]                                   \
                                                   + System::Environment::NewLine + oldPptFile[oldPartIdx]->Replace(oldPart, newPart)                    \
                                                   + System::Environment::NewLine + "END_PART";
                    } 
                    else
                    {
						// if exist, only insert partname for its section
                        if (-1 == FindLineIndexInFile(newPptFile, newPart))
                        {
							// Add if not found, then add this new part. If exist, no add
                            int endPartIdx = FindLineIndexInFile(newPptFile, "END_PART", newPartIdx);
                            if (-1 == endPartIdx)
                            {
                                AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", pptNewFileName);
                                return (false);
                            }
                            newPptFile[endPartIdx - 1] += System::Environment::NewLine + oldPptFile[oldPartIdx]->Replace(oldPart, newPart);
                        }
						else
						{
							AddErrorLog(eErrorCode::NEW_PART_IS_EXISTS_IN_NEW_PPT_FILE, newPart, pptNewFileName);
							return (false);
						}
                    }

                    if (-1 == FindLineIndexInFile(globalChangeFile, newPart))
                    {
                        for (int k=1; k<globalChangeFile->Length; k++)
                        {
                            if (")" == globalChangeFile[k])
                            {
                                globalChangeFile[k-1] += System::Environment::NewLine + "  ( _globalModify"
                                    + System::Environment::NewLine + "    ( -Scope Design )"
                                    + System::Environment::NewLine + "    ( -Save true )"
                                    + System::Environment::NewLine + "    ( -HardProp true )"
                                    + System::Environment::NewLine + "    ( -FromLib \"" + family->ToUpper() + "\" )"
                                    + System::Environment::NewLine + "    ( -FromCell \"" + oldPartName + "\" )"
                                    + System::Environment::NewLine + "    ( -FromProp \"PART_NUMBER\" \"" + oldPart + "\" )"
                                    + System::Environment::NewLine + "    ( -FromVer \"*\" )"
                                    + System::Environment::NewLine + "    ( -ToLib \"" + family->ToUpper() + "\" )"
                                    + System::Environment::NewLine + "    ( -ToCell \"" + newPartName + "\" )"
                                    + System::Environment::NewLine + "    ( -toProp \"PART_NUMBER\" \"" + newPart + "\" )"
                                    + System::Environment::NewLine + "    ( -ToVer \"*\" )"
                                    + System::Environment::NewLine + "  )";
                            }
                        }
                        File::WriteAllLines(globalChangeFileName, globalChangeFile);
                    }

                }

                File::WriteAllLines(pptNewFileName, newPptFile);
                delete newPptFile;
                return (true);
            }

            void DuplicateConceptProcess(String^ conceptLibPath)
            {
                ClearErrorLog();
                ClearDoneLog();

                String^ timeAsStr = "";
                DateTime dt = DateTime::Now;
                timeAsStr = dt.ToString("yyyy-MM-dd");

                // Prepare
                // 1. Load file
                AddMsg("Loading necessary files ...");
                String^ databasePath = FindFolder(conceptLibPath, "ConceptLibDatabase");
                if ( "" == databasePath )
                {
                    AddMsg("  --ERROR-- Can't find folder: " + conceptLibPath + "\\HOTS_ConceptLibDatabase");
                    goto SaveLog;
                }

                String^ oldConceptFileName = databasePath + "\\dbo_PK_Concept.csv";
                if ( false == File::Exists(oldConceptFileName) )
                {
                    AddMsg("  --ERROR-- Can't find file: " + oldConceptFileName);
                    AddErrorLog(eErrorCode::FILE_NOT_FOUND, "", oldConceptFileName);
                    goto SaveLog;
                }
                String^ newConceptFileName = databasePath + "\\" + timeAsStr + "_"      \
                                            + oldConceptFileName->Substring(databasePath->Length + 1, oldConceptFileName->Length - databasePath->Length - 1);
                if (true == File::Exists(newConceptFileName))
                {
                    File::Delete(newConceptFileName);
                }


                String^ oldReportFileName = databasePath + "\\dbo_PK_PReport.csv";
                if ( false == File::Exists(oldReportFileName) )
                {
                    AddMsg("  --ERROR-- Can't find file: " + oldReportFileName);
                    AddErrorLog(eErrorCode::FILE_NOT_FOUND, "", oldReportFileName);
                    goto SaveLog;
                }
                String^ newReportFileName = databasePath + "\\" + timeAsStr + "_"      \
                                            + oldReportFileName->Substring(databasePath->Length + 1, oldReportFileName->Length - databasePath->Length - 1);
                if (true == File::Exists(newReportFileName))
                {
                    File::Delete(newReportFileName);
                }

                String^ inputFileName = FindFile(databasePath, "input");
                if ( "" == inputFileName )
                {
                    AddMsg("  --ERROR-- Can't find file: " + inputFileName);
                    goto SaveLog;
                }

                array<String^>^ oldConceptFile = File::ReadAllLines(oldConceptFileName, Encoding::GetEncoding("shift-jis"));
                array<String^>^ newConceptFile = gcnew array<String^>(oldConceptFile->Length);
                int newConceptFileLineCount = 0;
                if ("" != oldConceptFile[0])
                {
                    newConceptFile[newConceptFileLineCount++] = oldConceptFile[0];
                    FillNullString(newConceptFile, newConceptFileLineCount);
                }
                else
                {
                    AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", oldConceptFileName);
                }

                array<String^>^ oldReportFile = File::ReadAllLines(oldReportFileName, Encoding::GetEncoding("shift-jis"));
                array<String^>^ newReportFile = gcnew array<String^>(oldReportFile->Length);
                int newReportFileLineCount = 0;
                if ("" != oldReportFile[0])
                {
                    newReportFile[newReportFileLineCount++] = oldReportFile[0];
                    FillNullString(newReportFile, newReportFileLineCount);
                }
                else
                {
                    AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, "", oldReportFileName);
                }

                array<String^>^ inputFile = File::ReadAllLines(inputFileName);

                // 2. Load Concept directory
                String^ dirPath = FindFolder(conceptLibPath, "ConceptDir");
                if ( "" == dirPath )
                {
                    AddMsg("  --ERROR-- Can't find folder: " + dirPath + "\\HOTS_ConceptDir");
                    goto SaveLog;
                }
                String^ directoryFileName = FindFile(dirPath, "directory");
                if ( "" == directoryFileName )
                {
                    AddMsg("  --ERROR-- Can't find file: " + directoryFileName);
                    goto SaveLog;
                }
                String^ conceptPath = cConceptCmd::GetDestFolderPath(dirPath);
                if ("" == conceptPath)
                {
                    AddErrorLog(eErrorCode::DIRECTORY_FILE_IS_NOT_CONTAIN_PATH, "", directoryFileName);
                    goto SaveLog;
                }

                // Delete all of new_*.ppt
                String^ pptFolderName = conceptPath + "\\PPT";
                String^ newPptFileName = "";
                do 
                {
                    newPptFileName = FindFileWithoutAddLog(pptFolderName, "new_");
                    if ("" != newPptFileName)
                    {
                        File::Delete(newPptFileName);
                    }
                } while ("" != newPptFileName);

                String^ globalChangeFileName = conceptPath + "\\global_change.txt";
                array<String^>^ globalChangeFile;
                if (true == File::Exists(globalChangeFileName))
                {
                    File::Delete(globalChangeFileName);
                }

                globalChangeFile = gcnew array<String^>(2);
                globalChangeFile[0] = "(";
                globalChangeFile[1] = ")";
                File::WriteAllLines(globalChangeFileName, globalChangeFile);
                delete globalChangeFile;

                String^ inputStr = "";
                String^ oldPart = "";
                String^ oldPartName = "";
                String^ oldPartNumber = "";
                String^ newPart = "";
                String^ newPartName = "";
                String^ newPartNumber = "";

                String^ oldReportLineStr = "";
                String^ newReportLineStr = "";

                int fStartIdx, fEndIdx;
                String^ family = "";

                int     oldConeptIndex = 0;
                int     newConeptIndex = 0;
                int     oldReportIndex = 0;

                // duplicate concept lib loop
                for (int i=0; i<inputFile->Length; i++)
                {
                    s_SpecialPart = false;
					s_MultiPart = false;
                    inputStr = inputFile[i];
                    int idx = inputStr->IndexOf(",");
                    oldPart         = inputStr->Substring(0, idx);
                    oldPart         = oldPart->ToUpper();
                    oldPartName     = oldPart->Substring(0, oldPart->IndexOf('-'));
                    int charIdx = oldPart->IndexOf('-') + 1;
                    oldPartNumber   = oldPart->Substring(charIdx, oldPart->Length - charIdx);

                    newPart = inputStr->Substring(idx + 1, inputStr->Length - (idx + 1));
                    newPart = newPart->ToUpper();
                    newPartName = newPart->Substring(0, newPart->IndexOf('-'));
                    charIdx = newPart->IndexOf('-') + 1;
                    newPartNumber   = newPart->Substring(charIdx, newPart->Length - charIdx);

                    oldConeptIndex = FindLineIndexInFile(oldConceptFile, oldPart);
                    newConeptIndex = FindLineIndexInFile(newConceptFile, newPart);
                    oldReportIndex = FindLineIndexInFile(oldReportFile, oldPart);

					// If oldPart find out in oldConceptFile and newPart not found in newConceptFile, then copy and rename this input part
                    if (-1 == oldConeptIndex)
                    {
                        oldConeptIndex = FindLineIndexInFile(oldConceptFile, oldPartName);
                        if (-1 == oldConeptIndex)
                        {
                            AddErrorLog(eErrorCode::PART_IS_NOT_EXISTS_IN_CONCEPT_FILE, oldPart, oldConceptFileName);
                            continue;
                        }
                        else
                        {
                            String^ firstPartName = oldConceptFile[oldConeptIndex];
                            int idx = firstPartName->IndexOf(",");
                            if (-1 != idx)
                            {
                                firstPartName = firstPartName->Substring(0, idx);
                                if (oldPartName == firstPartName)
                                {
                                    s_SpecialPart = true;
                                } 
                                else
                                {
                                    AddErrorLog(eErrorCode::PART_IS_NOT_EXISTS_IN_CONCEPT_FILE, oldPart, oldConceptFileName);
                                    continue;
                                }
                            }
                            else
                            {
                                AddErrorLog(eErrorCode::FILE_IS_NOT_VALID_FORMAT, oldPart, oldConceptFileName);
                                continue;
                            }
                        }
                    }
                    
                    // new concept exist & not special.
                    if (-1 != newConeptIndex && false == s_SpecialPart)
                    {
                        AddErrorLog(eErrorCode::NEW_PART_IS_EXISTS_IN_NEW_CONCEPT_FILE, newPart, newConceptFileName);
                        continue;
                    }
                    if (-1 == oldReportIndex)
                    {
                        AddErrorLog(eErrorCode::PART_IS_NOT_EXISTS_IN_REPORT_FILE, oldPart, oldReportFileName);
                        continue;
                    }
                    
                    
                    oldReportLineStr = oldReportFile[oldReportIndex];
                    newReportLineStr = oldReportLineStr->Replace(oldPart, newPart);
                    if (true == s_SpecialPart)
                    {
                        newReportLineStr = newReportLineStr->Replace(oldPartName, newPartName);
                    }
                    newReportFile[newReportFileLineCount++] = newReportLineStr;

                    // get family info
                    fStartIdx = oldReportLineStr->IndexOf(",") + 1;
                    fStartIdx = oldReportLineStr->IndexOf(",", fStartIdx) + 1;
                    fEndIdx   = oldReportLineStr->IndexOf(",", fStartIdx);
                    family    = oldReportLineStr->Substring(fStartIdx, fEndIdx - fStartIdx);

 					// Find parts which have the same part name but part number have _A, _B,... 
                    int     partIdx = oldReportLineStr->IndexOf(oldPart);
                    bool    firstFindPart = true;
                    String^ subOldPart       = oldPart;
                    String^ subOldPartName   = oldPartName;
                    String^ subOldPartNumber = oldPartNumber;
                    String^ subNewPart       = newPart;					
                    String^ subNewPartName   = newPartName;
                    String^ subNewPartNumber = newPartNumber;
					subOldPartRoot=oldPart;
					subNewPartRoot=newPart;

					s_MultiPart = false;
                    while (-1 != partIdx)
                    {   
                        partIdx = (true == s_SpecialPart)? oldReportLineStr->IndexOf(oldPartName, partIdx + subOldPart->Length + 1): oldReportLineStr->IndexOf(oldPart, partIdx + subOldPart->Length + 1);
                        if (-1 != partIdx)
                        {
                            firstFindPart = false;
                            if (false == s_SpecialPart)
                            {
                                fEndIdx          = oldReportLineStr->IndexOf(",", partIdx);
                                subOldPart       = oldReportLineStr->Substring(partIdx, fEndIdx - partIdx);
                                subOldPart       = subOldPart->ToUpper();
                                subOldPartName   = subOldPart->Substring(0, subOldPart->IndexOf('-'));
                                int charIdx      = subOldPart->IndexOf('-') + 1;
                                subOldPartNumber = subOldPart->Substring(charIdx, subOldPart->Length - charIdx);
                                subNewPart       = subOldPart->Replace(oldPart, newPart);
                                subNewPartNumber = subOldPartNumber->Replace(oldPartNumber, newPartNumber);
                            }
							AddMsg("Process duplicate from " + subOldPart + " to " + subNewPart);
                            // duplicate concept: copy and rename folder, chips.prt, my_edit.bat, my_edit.src, run my_edit.bat in window command line
                            if (false == ProcessDuplicatePart(conceptLibPath, conceptPath, family, subOldPart, subOldPartName, subOldPartNumber, subNewPart, subNewPartName, subNewPartNumber))
                            {
                                continue;
                            }

                            if (false == ProcessPptFile(conceptPath, family, subOldPart, subOldPartName, subNewPart, subNewPartName))
                            {
                                continue;
                            }

                            //sDoneLog->Text += "Duplicate from \"" + subOldPart + "\" to \"" + subNewPart + "\" is done" + System::Environment::NewLine;
                            
							sDoneLog->Text += subOldPart + "," + subNewPart + System::Environment::NewLine;
							
                        }
                        else
                        {
                            if (true == firstFindPart)
                            {
                                AddErrorLog(eErrorCode::CONCEPT01_IS_NOT_EXISTS_IN_REPORT_FILE, oldPart, oldReportFileName);
                            }
                        }
						s_MultiPart=true;
                    }

                    if (true == s_SpecialPart)
                    {
                        newConeptIndex = FindLineIndexInFile(newConceptFile, newPartName);
                        if (-1 == newConeptIndex)
                        {
                            newConceptFile[newConceptFileLineCount++] = newPartName + "," + GetStatusString(oldConceptFile[oldConeptIndex]) + ",Add_by_program,From_" + oldPartName + "," + timeAsStr;
                        }
                        else
                        {
                            if (false == newConceptFile[newConeptIndex]->Contains(oldPartName))
                            {
                                newConceptFile[newConceptFileLineCount++] = newPartName + "," + GetStatusString(oldConceptFile[oldConeptIndex]) + ",Add_by_program,From_" + oldPartName + "," + timeAsStr;
                            }
                        }
                    }
                    else
                    {
                        newConceptFile[newConceptFileLineCount++] = subNewPart + "," + GetStatusString(oldConceptFile[oldConeptIndex])+ ",Add_by_program,From_" + subOldPart + "," + timeAsStr;
                    }
                }

SaveLog:
                if (inputFile)
                {
                    delete inputFile;
                }
                SaveErrorLog(conceptLibPath, "ErrorLog.txt");
                
                SaveDoneLog(conceptLibPath, "DoneLog.txt");

                array<String^>^ newReportToSaveFile = gcnew array<String^>(newReportFileLineCount);
                for (int k=0; k<newReportFileLineCount; k++)
                {
                    newReportToSaveFile[k] = newReportFile[k];
                }
                File::WriteAllLines(newReportFileName, newReportToSaveFile, Encoding::GetEncoding("shift-jis"));
                delete newReportFile;
                delete newReportToSaveFile;

                array<String^>^ newConceptToSaveFile = gcnew array<String^>(newConceptFileLineCount);
                for (int k=0; k<newConceptFileLineCount; k++)
                {
                    newConceptToSaveFile[k] = newConceptFile[k];
                }
                File::WriteAllLines(newConceptFileName, newConceptToSaveFile, Encoding::GetEncoding("shift-jis"));
                delete newConceptFile;
                delete newConceptToSaveFile;

                AddMsg("Completed!");
            }


            void F2AddMsg(String^ msg)
            {
                tF2Disp->Text += msg + System::Environment::NewLine;
                tF2Disp->Update();
            }

            bool CheckDoneCount(String^ conceptLibPath, String^ conceptPath)
            {
                String^ doneListFileName = conceptLibPath + "\\DoneLog.txt";
                String^ globalChangeFileName = conceptPath + "\\global_change.txt";
                if (false == File::Exists(doneListFileName) || false == File::Exists(globalChangeFileName))
                {
                    return (false);
                }

                array<String^>^ doneListFile = File::ReadAllLines(doneListFileName, Encoding::GetEncoding("shift-jis"));
                int doneCount = 0;
                for (int i=0; i<doneListFile->Length; i++)
                {
                    if (doneListFile[i]->Contains(","))
                    {
                        doneCount++;
                    }
                }

                array<String^>^ globalChangeFile = File::ReadAllLines(globalChangeFileName, Encoding::GetEncoding("shift-jis"));
                int globalChangeCount = 0;
                for (int i=0; i<globalChangeFile->Length; i++)
                {
                    if (globalChangeFile[i]->Contains("( _globalModify"))
                    {
                        globalChangeCount++;
                    }
                }

                if (doneCount != globalChangeCount || 0 == globalChangeCount || 0 == doneCount )
                {
                    return (false);
                }

                return (true);
            }

            void F2ClearMsg()
            {
                tF2Disp->Clear();
            }

            void CheckDuplicateConceptProcess(String^ conceptLibPath)
            {
                // Prepare
                String^ dbCheckList = "";
                String^ conceptCheckList = "";
                String^ globalChangeCheckList = "";

                F2ClearMsg();

                // 1. Load file
                F2AddMsg("Loading necessary files ...");
                String^ databasePath = conceptLibPath + "\\HOTS_ConceptLibDatabase";
                if ( false == Directory::Exists(databasePath) )
                {
                    F2AddMsg("  --ERROR-- Can't find folder: " + databasePath);
                    return;
                }

                String^ oldConceptFileName = databasePath + "\\dbo_PK_Concept.csv";
                if ( false == File::Exists(oldConceptFileName) )
                {
                    F2AddMsg("  --ERROR-- Can't find file: " + oldConceptFileName);
                    return;
                }
                String^ newConceptFileName = FindFile(databasePath, "_dbo_PK_Concept.csv");
                if ("" == newConceptFileName)
                {
                    F2AddMsg("  --ERROR-- Can't find new concept file: ");
                    return;
                }


                String^ oldReportFileName = databasePath + "\\dbo_PK_PReport.csv";
                if ( false == File::Exists(oldReportFileName) )
                {
                    F2AddMsg("  --ERROR-- Can't find file: " + oldReportFileName);
                    return;
                }
                String^ newReportFileName = FindFile(databasePath, "_dbo_PK_PReport.csv");
                if ("" == newReportFileName)
                {
                    F2AddMsg("  --ERROR-- Can't find new report file: ");
                    return;
                }

                String^ inputFileName = FindFile(databasePath, "input");
                if ( "" == inputFileName )
                {
                    F2AddMsg("  --ERROR-- Can't find input file");
                    return;
                }

                // step 1. Load files
                array<String^>^ oldConceptFile = File::ReadAllLines(oldConceptFileName);
                array<String^>^ newConceptFile = File::ReadAllLines(newConceptFileName);
                array<String^>^ oldReportFile  = File::ReadAllLines(oldReportFileName);
                array<String^>^ newReportFile  = File::ReadAllLines(newReportFileName);
                array<String^>^ inputFile      = File::ReadAllLines(inputFileName);

                // Load Concept directory
                String^ dirPath = conceptLibPath + "\\HOTS_ConceptDir";
                if ( false == Directory::Exists(dirPath) )
                {
                    F2AddMsg("  --ERROR-- Can't find folder: " + dirPath);
                    return;
                }
                String^ directoryFileName = dirPath + "\\directory.txt";
                if ( false == File::Exists(directoryFileName) )
                {
                    F2AddMsg("  --ERROR-- Can't find file: " + directoryFileName);
                    return;
                }
                String^ conceptPath = cConceptCmd::GetDestFolderPath(dirPath);
                if ("" == conceptPath)
                {
                    F2AddMsg("Cannot find the Path in file directory: " + directoryFileName);
                    return;
                }

                String^ inputStr = "";
				String^ inputStr1 = "";
                String^ oldPart = "";
                String^ oldPartName = "";
                String^ oldPartNumber = "";
                String^ newPart = "";
                String^ newPartName = "";
                String^ newPartNumber = "";
				String^ tempStr1="";

                String^ oldReportLineStr = "";
                String^ newReportLineStr = "";

                int fStartIdx, fEndIdx;
                String^ family = "";
                String^ formattedFamily = "";

                int     oldConeptIndex = 0;
                int     newConeptIndex = 0;
                int     oldReportIndex = 0;
                int     newReportIndex = 0;

                // duplicate concept lib loop
                for (int i=0; i<inputFile->Length; i++)
                {
                    s_SpecialPart = false;
                    inputStr = inputFile[i];
                    int idx = inputStr->IndexOf(",");
                    oldPart         = inputStr->Substring(0, idx);
                    oldPart         = oldPart->ToUpper();
                    oldPartName     = oldPart->Substring(0, oldPart->IndexOf('-'));
                    int charIdx = oldPart->IndexOf('-') + 1;
                    oldPartNumber   = oldPart->Substring(charIdx, oldPart->Length - charIdx);

                    newPart = inputStr->Substring(idx + 1, inputStr->Length - (idx + 1));
                    newPart = newPart->ToUpper();
                    newPartName = newPart->Substring(0, newPart->IndexOf('-'));
                    charIdx = newPart->IndexOf('-') + 1;
                    newPartNumber   = newPart->Substring(charIdx, newPart->Length - charIdx);

                    F2AddMsg("Checking duplicate from \"" + oldPart + "\" to \"" + newPart + "\"");

                    oldConeptIndex = FindLineIndexInFile(oldConceptFile, oldPart);
                    newConeptIndex = FindLineIndexInFile(newConceptFile, newPart);

                    // check 2.a
                    if (-1 == oldConeptIndex)
                    {
                        oldConeptIndex = FindLineIndexInFile(oldConceptFile, oldPartName);
                        if (-1 == oldConeptIndex)
                        {
                            dbCheckList += oldPart + ", " + newPart + ", FAIL, Original concept file does not contain part: \"" + oldPart + "\"" + System::Environment::NewLine;
                            continue;
                        }
                        else
                        {
                            String^ firstPartName = oldConceptFile[oldConeptIndex];
                            int idx = firstPartName->IndexOf(",");
                            if (-1 != idx)
                            {
                                firstPartName = firstPartName->Substring(0, idx);
                                if (oldPartName == firstPartName)
                                {
                                    newConeptIndex = FindLineIndexInFileWithTwoString(newConceptFile, newPartName, oldPartName);
                                    s_SpecialPart = true;
                                } 
                                else
                                {
                                    dbCheckList += oldPart + ", " + newPart + ", FAIL, Original concept file does not contain part: \"" + oldPart + "\"" + System::Environment::NewLine;
                                    continue;
                                }
                            }
                            else
                            {
                                dbCheckList += oldPart + ", " + newPart + ", FAIL, Line: \"" + oldConeptIndex + "\" is formated incorrect" + System::Environment::NewLine;
                                continue;
                            }
                        }
                    }
                    if (-1 == newConeptIndex)
                    {
                        // TODO: function 1 ko copy va rename part
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, Function 1 don't copy & rename part: \"" + newPart + "\"" + System::Environment::NewLine;
                        continue;
                    }

                    // check 2.b
					String^ oldStatus=GetStatusString(oldConceptFile[oldConeptIndex]);
					String^ newStatus=GetStatusString(newConceptFile[newConeptIndex])->ToLower();
                    if (oldStatus != newStatus)
                    {
                        // TODO: 
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, The status of part \"" + newPart + "\" in the new concept database is not the same as the old part." + System::Environment::NewLine;
                        continue;
                    }

                    // check 2.c
                    if (false == newConceptFile[newConeptIndex]->Contains("Add_by_program"))
                    {
                        // TODO: 
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, DWN of part \"" + newPart + "\" in the new concept database is error." + System::Environment::NewLine;
                        continue;
                    }
					bool newPartAddedFlag=false;
					//bool exitForFlag=false;
					int currentInputFileIndex=i;
					String^ oldPart1="";
					String^ oldPartTemp1="";
					String^ oldPartName1="";
					String^ newPartTemp="";
					if(true==s_SpecialPart)
						newPartTemp=newPartName;
					else
						newPartTemp=newPart;
                    // check 2.d
                    tempStr1= (true == s_SpecialPart)? oldPartName: oldPart;
                    if (false == newConceptFile[newConeptIndex]->Contains("From_" + tempStr1))
                    {
						for(int j=0; j<inputFile->Length; j++)
						{														
							inputStr1 = inputFile[j];							
							if (true == inputStr1->Contains(newPartTemp))
							{
								int idx1 = inputStr1->IndexOf(",");
								oldPart1         = inputStr1->Substring(0, idx1);
								oldPart1         = oldPart1->ToUpper();
								oldPartName1     = oldPart1->Substring(0, oldPart1->IndexOf('-'));
								if(true==s_SpecialPart)
								{
									oldPartTemp1=oldPartName1;
								}
								else
								{
									oldPartTemp1=oldPart1;
								}
								if((j<currentInputFileIndex)&&(true == newConceptFile[newConeptIndex]->Contains("From_"+oldPartTemp1)))
								{
									newPartAddedFlag=true;
									//exitForFlag=true;
									j=inputFile->Length;									
								}
							}
							
						}//end for j
                        if (false==newPartAddedFlag)
						{
							// TODO: 
							dbCheckList += oldPart + ", " + newPart + ", FAIL, Note of part \"" + newPartTemp + "\" in the new concept database is error." + System::Environment::NewLine;
							continue;
						}
						else
						{
							if(false==s_SpecialPart)
							{
								dbCheckList += oldPart + ", " + newPart + ", FAIL, New Part \"" + newPartTemp + "\" existed in new concept database file." + System::Environment::NewLine;
							}
							continue;
						}
						
                    }

                    oldReportIndex = FindLineIndexInFile(oldReportFile, oldPart);
                    if (true == s_SpecialPart)
                    {
                        newReportIndex = FindLineIndexInFileWithTwoString(newReportFile, "," + newPart + ",", "," + newPartName + ",");
                    } 
                    else
                    {
                        newReportIndex = FindLineIndexInFile(newReportFile, newPart);
                    }

                    // check 3
                    if (-1 == oldReportIndex)
                    {
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, Original report file does not contain part: \"" + oldPart + "\"" + System::Environment::NewLine;
                        continue;
                    }
                    if (-1 == newReportIndex)
                    {
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, New report file does not contain part: \"" + newPart + "\"" + System::Environment::NewLine;
                        continue;
                    }
					String^ tempStr="";
                    tempStr = oldReportFile[oldReportIndex]->Replace(oldPart, newPart)->Replace(oldPartName, newPartName);
                    if (newReportFile[newReportIndex] != tempStr)
                    {
                        // TODO: 
                        dbCheckList += oldPart + ", " + newPart + ", FAIL, Information of part \"" + newPart + "\" in the new report database is not the same as the infomation of ori part: \"" + oldPart + "\"" + System::Environment::NewLine;
                        continue;
                    }

                    // concept check list ok
                    dbCheckList += oldPart + ", " + newPart + ", PASS, " + System::Environment::NewLine;

                    //check 4
                    // get family info
                    oldReportLineStr = oldReportFile[oldReportIndex];
                    newReportLineStr = newReportFile[newReportIndex];

                    fStartIdx = oldReportLineStr->IndexOf(",") + 1;
                    fStartIdx = oldReportLineStr->IndexOf(",", fStartIdx) + 1;
                    fEndIdx   = oldReportLineStr->IndexOf(",", fStartIdx);
                    family    = oldReportLineStr->Substring(fStartIdx, fEndIdx - fStartIdx);
                    formattedFamily = family->ToLower()->Replace("-", "_");

                    int     partIdx = oldReportLineStr->IndexOf(oldPart);
                    bool    firstFindPart = true;
                    String^ subOldPart       = oldPart;
                    String^ subOldPartName   = oldPartName;
                    String^ subOldPartNumber = oldPartNumber;
                    String^ subNewPart       = newPart;
                    String^ subNewPartName   = newPartName;
                    String^ subNewPartNumber = newPartNumber;
                    while (-1 != partIdx)
                    {
                        partIdx = (true == s_SpecialPart)? oldReportLineStr->IndexOf(oldPartName, partIdx + subOldPart->Length + 1): oldReportLineStr->IndexOf(oldPart, partIdx + subOldPart->Length + 1);
                        if (-1 != partIdx)
                        {
                            firstFindPart = false;
                            if (false == s_SpecialPart)
                            {
                                fEndIdx          = oldReportLineStr->IndexOf(",", partIdx);
                                subOldPart       = oldReportLineStr->Substring(partIdx, fEndIdx - partIdx);
                                subOldPart       = subOldPart->ToUpper();
                                subOldPartName   = subOldPart->Substring(0, subOldPart->IndexOf('-'));
                                int charIdx      = subOldPart->IndexOf('-') + 1;
                                subOldPartNumber = subOldPart->Substring(charIdx, subOldPart->Length - charIdx);
                                subNewPart       = subOldPart->Replace(oldPart, newPart);
                                subNewPartNumber = subOldPartNumber->Replace(oldPartNumber, newPartNumber);
                            }

                            // check 4.a
                            String^ oldPartPath = (true == s_SpecialPart)? subOldPartName :subOldPart->Replace("-", "#2D");
                            oldPartPath = conceptPath + "\\" + formattedFamily + "\\" + oldPartPath;

                            String^ newPartPath = (true == s_SpecialPart)? subNewPartName :subNewPart->Replace("-", "#2D");
                            newPartPath = conceptPath + "\\" + formattedFamily + "\\" + newPartPath;
                            if (false == Directory::Exists(newPartPath))
                            {
                                // TODO: 
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, new part \"" + subNewPart + "\" does not exist in family directory: \"" + family + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            // check 4.b
                            String^ chipsFileName = newPartPath + "\\chips\\chips.prt";
                            if (false == File::Exists(chipsFileName))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, File not found: \"" + chipsFileName + "\"" + System::Environment::NewLine;
                                continue;
                            }
                            String^ tempStr = "";
                            String^ tempSubOldPart = (true == s_SpecialPart)? subOldPartName: subOldPart;
                            String^ tempSubNewPart = (true == s_SpecialPart)? subNewPartName: subNewPart;
                            array<String^>^ chipsFile = File::ReadAllLines(chipsFileName);
                            for (int l=0; l<chipsFile->Length; l++)
                            {
                                tempStr = chipsFile[l]->ToUpper();
                                if (true == tempStr->Contains("PRIMITIVE '"))
                                {
                                    if (true == tempStr->Contains(tempSubOldPart) || false == tempStr->Contains(tempSubNewPart))
                                    {
                                        // TODO: 
                                        conceptCheckList += oldPart + ", " + newPart + ", FAIL, chips.prt of part: \"" + tempSubNewPart + "\" is not the same as chips.prt of ori part: \"" + tempSubOldPart + "\"" + System::Environment::NewLine;
                                        break;
                                    }
                                } 
                                else if (true == tempStr->Contains("PART_NAME"))
                                {
                                    if (true == tempStr->Contains(tempSubOldPart) || false == tempStr->Contains(tempSubNewPart))
                                    {
                                        // TODO:
                                        conceptCheckList += oldPart + ", " + newPart + ", FAIL, chips.prt of part: \"" + tempSubNewPart + "\" is not the same as chips.prt of ori part: \"" + tempSubOldPart + "\"" + System::Environment::NewLine;
                                        break;
                                    }
                                }
                                else if (true == tempStr->Contains("BODY_NAME"))
                                {
                                    if (true == tempStr->Contains(tempSubOldPart) || false == tempStr->Contains(tempSubNewPart))
                                    {
                                        // TODO:
                                        conceptCheckList += oldPart + ", " + newPart + ", FAIL, chips.prt of part: \"" + tempSubNewPart + "\"is not the same as chips.prt of ori part: \"" + tempSubOldPart + "\"" + System::Environment::NewLine;
                                        break;
                                    }
                                }
                            }
                            delete chipsFile;

                            // check 4.c
                            int dirCnt;
                            String^ listAllSymDirInOldPart = cFileOperationCmds::ListAllFolderName(oldPartPath, "sym_", dirCnt);
                            String^ listAllSymDirInNewPart = cFileOperationCmds::ListAllFolderName(newPartPath, "sym_", dirCnt);
                            if (listAllSymDirInNewPart != listAllSymDirInOldPart)
                            {
                                // TODO:
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, Sym_X directory of part \"" + subNewPart + "\" is not the same as Sym_Y directory of part \"" + subOldPart + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            String^ oldSymFileName = "";
                            String^ newSymFileName = "";
                            String^ symName = "";
                            array<String^>^ oldSymFile;
                            array<String^>^ newSymFile;
                            for (int k=1; k<=dirCnt; k++)
                            {
                                symName = "sym_" + k;
                                oldSymFileName = oldPartPath + "\\" + symName + "\\symbol.css";
                                newSymFileName = newPartPath + "\\" + symName + "\\symbol.css";

                                if (false == File::Exists(oldSymFileName) || false == File::Exists(newSymFileName) || 0 == dirCnt)
                                {
                                    // TODO: 
                                    conceptCheckList += oldPart + ", " + newPart + ", FAIL, File symbol.css in " + symName + " of part \"" + subNewPart + "\" is not the same as the file symbol.css in " + symName + " of part \"" + subOldPart + "\"" + System::Environment::NewLine;
                                    continue;
                                }
#if 0
                                oldSymFile = File::ReadAllLines(oldSymFileName);
                                newSymFile = File::ReadAllLines(newSymFileName);
                                if (oldSymFile->Length != newSymFile->Length)
                                {
                                    // TODO:
                                    conceptCheckList += oldPart + ", " + newPart + ", FAIL, File symbol.css in " + symName + " of part \"" + subNewPart + "\" is not the same as the file symbol.css in " + symName + " of part \"" + subOldPart + "\"" + System::Environment::NewLine;
                                    continue;
                                }
                                for (int h=0; h<oldSymFile->Length; h++)
                                {
                                    if (oldSymFile[h] != newSymFile[h])
                                    {
                                        // TODO: 
                                        conceptCheckList += oldPart + ", " + newPart + ", FAIL, file symbol.css in " + symName + " of part \"" + subNewPart + "\" is not the same as the file symbol.css in " + symName + " of part \"" + subOldPart + "\"" + System::Environment::NewLine;
                                        break;
                                    }
                                }
#endif
                            }

                            //check 4.d
                            String^ entityPath = newPartPath + "\\entity";
                            if (false == Directory::Exists(entityPath))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, Folder not found: \"" + entityPath + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            //check 4.e
                            String^ verilogFileName = entityPath + "\\verilog.v";
                            if (false == File::Exists(verilogFileName))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, File not found: \"" + verilogFileName + "\"" + System::Environment::NewLine;
                                continue;
                            }
                            array<String^>^ verilogFile = File::ReadAllLines(verilogFileName);
                            bool foundText = false;
                            tempSubNewPart = (true == s_SpecialPart)? subNewPartName: subNewPart;
                            for (int l=0; l<verilogFile->Length; l++)
                            {
                                if (true == verilogFile[l]->ToUpper()->Contains(tempSubNewPart))
                                {
                                    foundText = true;
                                    break;
                                } 
                            }
                            delete verilogFile;
                            if (false == foundText)
                            {
                                // TODO:
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, Entity of part: \"" + subNewPart + "\" is error." + System::Environment::NewLine;
                                continue;
                            }

                            // check 5: PPT files
                            // check 5.a
                            String^ pptPath = conceptPath + "\\PPT";
                            if (false == Directory::Exists(pptPath))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, Folder not found: \"" + pptPath + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            String^ oldPptFileName = pptPath + "\\" + formattedFamily->ToLower() + ".ppt";
                            if (false == File::Exists(oldPptFileName))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, File not found: \"" + oldPptFileName + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            if ("" == formattedFamily)
                            {
                                AddMsg("+++++++++++++Family name error! ++++++++++++++");
                            }
                            String^ newPptFileName = pptPath + "\\new_" + formattedFamily->ToLower() + ".ppt";
                            if (false == File::Exists(newPptFileName))
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, File not found: \"" + newPptFileName + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            // check 5.b
                            array<String^>^ oldPptFile = File::ReadAllLines(oldPptFileName);
                            array<String^>^ newPptFile = File::ReadAllLines(newPptFileName);
                            int oldPptIndex = FindLineIndexInFile(oldPptFile, subOldPart);
                            int newPptIndex = FindLineIndexInFile(newPptFile, subNewPart);

                            if (-1 == oldPptIndex)
                            {
                                // TODO: 
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, Original PPT file \"" + family->ToLower() + ".ppt\" does not have part: \"" + subOldPart + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            if (-1 == newPptIndex)
                            {
                                // TODO: 
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, New PPT file \"new_" + family->ToLower() + ".ppt\" does not have  part: \"" + subNewPart + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            if (newPptFile[newPptIndex] != oldPptFile[oldPptIndex]->Replace(subOldPart, subNewPart))
                            {
                                // TODO: 
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, New PPT file \"new_" + family->ToLower() + ".ppt\" does not have part: \"" + subNewPart + "\"" + System::Environment::NewLine;
                                continue;
                            }

                            // concept check list ok
                            conceptCheckList += oldPart + ", " + newPart + ", PASS, " + System::Environment::NewLine;

                            //check 6
                            if (true == globalChangeCheckList->Contains(subOldPart + "," + subNewPart))
                            {
                                continue;
                            }

                            String^ globalChangeFileName = conceptPath + "\\global_change.txt";
                            if (false == File::Exists(globalChangeFileName))
                            {
                                globalChangeCheckList += subOldPart + ", " + subNewPart + ", FAIL, File not found: " + globalChangeFileName + System::Environment::NewLine;
                                continue;
                            }

                            array<String^>^ globalChangeFile = File::ReadAllLines(globalChangeFileName);
                            int newPartIndex = FindLineIndexInFile(globalChangeFile, subNewPart);
                            if (-1 == newPartIndex)
                            {
                                globalChangeCheckList += subOldPart + ", " + subNewPart + ", FAIL, Part \"" + subNewPart + "\" does not exist in global_change.txt" + System::Environment::NewLine;
                                continue;
                            }

                            int idxOfFromLib = newPartIndex;
                            bool partFound = false;
                            while (idxOfFromLib > (newPartIndex - 7))
                            {
                                if (true == globalChangeFile[idxOfFromLib]->Contains("-FromLib"))
                                {
                                    partFound = true;
                                    tempSubOldPart = (true == s_SpecialPart)? subOldPartName: subOldPart;
                                    tempSubNewPart = (true == s_SpecialPart)? subNewPartName: subNewPart;
                                    if( (false == globalChangeFile[idxOfFromLib]->Contains("-FromLib") || false == globalChangeFile[idxOfFromLib]->Contains(family)) ||                     \
                                        (false == globalChangeFile[idxOfFromLib+1]->Contains("-FromCell") || false == globalChangeFile[idxOfFromLib+1]->Contains(tempSubOldPart)) ||            \
                                        (false == globalChangeFile[idxOfFromLib+2]->Contains("-FromProp") || false == globalChangeFile[idxOfFromLib+2]->Contains(subOldPart)) ||            \
                                        (false == globalChangeFile[idxOfFromLib+4]->Contains("-ToLib") || false == globalChangeFile[idxOfFromLib+4]->Contains(family)) ||                   \
                                        (false == globalChangeFile[idxOfFromLib+5]->Contains("-ToCell") || false == globalChangeFile[idxOfFromLib+5]->Contains(tempSubNewPart)) ||              \
                                        (false == globalChangeFile[idxOfFromLib+6]->Contains("-toProp") || false == globalChangeFile[idxOfFromLib+6]->Contains(subNewPart)) )
                                    {
                                        partFound = false;
                                    }
                                    break;
                                }
                                idxOfFromLib--;
                            }

                            if (false == partFound)
                            {
                                globalChangeCheckList += subOldPart + ", " + subNewPart + ", FAIL, Part \"" + subNewPart + "\" in file global_change.txt is not correct." + System::Environment::NewLine;
                                continue;
                            }

                            // every thing is ok
                            //globalChangeCheckList += subOldPart + ", " + subNewPart + ", PASS, " + System::Environment::NewLine;
                            globalChangeCheckList += subOldPart + "," + subNewPart + System::Environment::NewLine;
                        }
                        else
                        {
                            if (true == firstFindPart)
                            {
                                conceptCheckList += oldPart + ", " + newPart + ", FAIL, \"Concept01\" of part: \"" + newPart + "\" is not exist in report file" + System::Environment::NewLine;
                            }
                        }
                    }
                }
                // Save check list files
                array<String^>^ dbCheckListFile = gcnew array<String^>(1);
                dbCheckListFile[0] = dbCheckList;
                File::WriteAllLines(conceptLibPath + "\\HOT_DB_check.lst", dbCheckListFile);
                delete dbCheckListFile;

                array<String^>^ conceptCheckListFile = gcnew array<String^>(1);
                conceptCheckListFile[0] = conceptCheckList;
                File::WriteAllLines(conceptLibPath + "\\ConceptLIB_check.lst", conceptCheckListFile);
                delete conceptCheckListFile;

                array<String^>^ globalChangeCheckListFile = gcnew array<String^>(1);
                globalChangeCheckListFile[0] = globalChangeCheckList;
                File::WriteAllLines(conceptLibPath + "\\GlobalChange_check.lst", globalChangeCheckListFile);
                delete globalChangeCheckListFile;

                bool isPass = CheckDoneCount(conceptLibPath, conceptPath);
                if (true == isPass)
                {
                    F2AddMsg("Done!");
                } 
                else
                {
                    F2AddMsg("FAIL, Done list count is not match with golbal_change list count!");
                }
            }

#pragma endregion
private: System::Void tBrowser_Click(System::Object^  sender, System::EventArgs^  e) 
         {
             if (System::Windows::Forms::DialogResult::OK == tFolder->ShowDialog())
             {
                 tOriText->Text = tFolder->SelectedPath;
                 tOriText->Update();
                 DuplicateConceptProcess(tFolder->SelectedPath);
             }
         }
private: System::Void sF2LoadBnt_Click(System::Object^  sender, System::EventArgs^  e) 
         {
             if (System::Windows::Forms::DialogResult::OK == tFolder->ShowDialog())
             {
                 tF2OriText->Text = tFolder->SelectedPath;
                 tF2OriText->Update();
                 CheckDuplicateConceptProcess(tFolder->SelectedPath);
             }
         }
};
}

